local desc_vanished_dragon = [[
  # 忠胆英杰（明忠模式）简介

  ---

  规则修改：
   1.一名角色一回合摸牌数不得超过30

  2.一名角色一回合累计发动同一技能超过15次则失效

  3.初始时后置位角色获得补偿6号位以后+1甲，9，10号位2甲
]]
local U = require "packages/utility/utility"
local Tt= require 'packages/jbs/record/Theorem'


local getnum=function (n)
  if n>=15 then
    return n-5
  elseif n>9 and n<15 then
    return n-4
  elseif n>3 and n<=9 then
    return n-3
  else 
    return n
  end
end

local vanished_dragon_getLogic = function()
  local vanished_dragon_logic = GameLogic:subclass("vanished_dragon_logic")
  --[[
  function GameLogic:prepareForStart()
    local room = self.room
    local players = room:getAllPlayers()

    self:addTriggerSkill(GameRule)
    for _, trig in ipairs(Fk.global_trigger) do
      if trig.name ~= "mobile_effect" then  --关闭手杀特效
        self:addTriggerSkill(trig)
      end
    end
    self.room:sendLog{ type = "$GameStart" }
  end
  --]]  

  function vanished_dragon_logic:initialize(room)
    GameLogic.initialize(self, room)
    self.role_table = {nil, nil, nil, nil, nil, 
    {"hidden", "loyalist", "rebel", "rebel", "rebel", "renegade"},
    {"hidden", "loyalist", "loyalist", "rebel", "rebel", "rebel", "renegade"}, 
    {"hidden", "loyalist", "loyalist", "rebel", "rebel", "rebel", "rebel", "renegade"} ,
    {"hidden", "loyalist", "loyalist","loyalist", "rebel", "rebel", "rebel", "rebel", "renegade"},
    {"hidden", "loyalist", "loyalist","loyalist", "rebel", "rebel", "rebel", "rebel", "renegade","renegade"}}
  end

  function vanished_dragon_logic:assignRoles()
    local room = self.room
    local players = room.players
    local n = #players
    local roles = self.role_table[n]
    table.shuffle(roles)

    room:setTag("ShownLoyalist", nil)
    for i = 1, n do
      local p = players[i]
      p.role = roles[i]
      if p.role == "loyalist" and not room:getTag("ShownLoyalist") then
        room:setPlayerProperty(p, "role_shown", true)
        room:broadcastProperty(p, "role")
        room:setTag("ShownLoyalist", p.id)
        p.role = "lord"
      else
        room:notifyProperty(p, p, "role")
      end
    end
  end

  function vanished_dragon_logic:prepareDrawPile()
    local room = self.room
    local allCardIds = Fk:getAllCardIds()
    local blacklist = {"snatch", "supply_shortage", "ex_nihilo", "amazing_grace", "collateral", "nullification", "lightning", "eight_diagram", "qinggang_sword", "blade"}
    local whitelist = {"diversion", "paranoid", "reinforcement", "abandoning_armor", "crafty_escape", "floating_thunder", "glittery_armor", "seven_stars_sword", "steel_lance"}
    for i = #allCardIds, 1, -1 do
      local card = Fk:getCardById(allCardIds[i])
      local name = card.name
      if (card.is_derived and not table.contains(whitelist, name)) or table.contains(blacklist, name) then
        local id = allCardIds[i]
        table.removeOne(allCardIds, id)
        table.insert(room.void, id)
        room:setCardArea(id, Card.Void, nil)
      end
    end
  
    local seed = math.random(2 << 32 - 1)
    table.shuffle(filterCardIds,seed)
    room.draw_pile = filterCardIds
    for _, id in ipairs(room.draw_pile) do
      room:setCardArea(id, Card.DrawPile, nil)
    end
    room:doBroadcastNotify("PrepareDrawPile", seed)
  end

  function vanished_dragon_logic:chooseGenerals()
    local room = self.room
    
    --Tt.remakegeneralpile(room)
    local generalNum = room:getSettings('generalNum')
    local n = room:getSettings('enableDeputy') and 2 or 1
    local lord = room:getLord()
    room.current = lord
    lord.role = "loyalist"
    for _, p in ipairs(room.players) do
      if p.role == "hidden" then
        p.role = "lord"
        room:notifyProperty(p, p, "role")
      end
       p:setMark("@seat", "seat#" .. tostring(p.seat))
      p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", "seat#" .. tostring(p.seat)})
    end

    room:doBroadcastNotify("ShowToast", "<b>" .. lord._splayer:getScreenName() .. "</b>" .. Fk:translate("vd_intro"))
    local lordame=lord._splayer:getScreenName()
    local lord_generals = {}
    local offgennum=getnum(generalNum)
    local prigennum=generalNum-offgennum
    local ifpri=true
    if lord ~= nil then
      local generals = {}
      local lordlist = {}
      local lordpools = {}
      --[[
      table.insertTable(generals, Fk:getGeneralsRandomly(generalNum, Fk:getAllGenerals(), table.map(generals, function (g)
        return g.name
      end)))
      --]]
  

      generals = table.map(Fk:getGeneralsRandomly(offgennum, Fk:getAllGenerals(), nil,
            (function(p) return not Tt.isoff(p) end)), function(g) return g.name end)
      local prigenerals=table.map(Fk:getGeneralsRandomly(prigennum, Fk:getAllGenerals(), nil,
      (function(p) return  Tt.isoff(p) end)), function(g) return g.name end)
      
      table.insertTable(generals,prigenerals)
      for _, general in ipairs({"cuiyan", "ty__huangfusong"}) do
        if not table.contains(room.disabled_packs, Fk.generals[general].package.name) and
          not table.contains(room.disabled_generals, general) and not table.find(generals, function(g)
            return g.trueName == "cuiyan" or g.trueName == "huangfusong"
          end) then
          table.insert(lordlist, general)
        end
      end
      --[[
      for i = 1, #generals do
        generals[i] = generals[i].name
      end
      --]]
      lordpools = table.simpleClone(generals)
      table.insertTable(lordpools, lordlist)
      lord_generals = room:askForGeneral(lord, lordpools, n)
      local lord_general, deputy
      if type(lord_generals) == "table" then
        deputy = lord_generals[2]
        lord_general = lord_generals[1]
      else
        lord_general = lord_generals
        lord_generals = {lord_general}
      end

      room:setPlayerGeneral(lord, lord_general, true)
      room:askForChooseKingdom({lord})
      room:broadcastProperty(lord, "general")
      room:broadcastProperty(lord, "kingdom")
      room:setDeputyGeneral(lord, deputy)
      room:broadcastProperty(lord, "deputyGeneral")

      
      local canAttachSkill = function(player, skillName)
        local skill = Fk.skills[skillName]
        if not skill then
          fk.qCritical("Skill: "..skillName.." doesn't exist!")
          return false
        end
        if skill.lordSkill and (player.role ~= "lord" or #room.players < 5) then
          return false
        end

        if #skill.attachedKingdom > 0 and not table.contains(skill.attachedKingdom, player.kingdom) then
          return false
        end

        return true
      end

      local lord_skills = {}
      for _, s in ipairs(Fk.generals[lord.general].skills) do
        if canAttachSkill(lord, s.name) then
          table.insertIfNeed(lord_skills, s.name)
        end
      end
      for _, sname in ipairs(Fk.generals[lord.general].other_skills) do
        if canAttachSkill(lord, sname) then
          table.insertIfNeed(lord_skills, sname)
        end
      end

      local deputyGeneral = Fk.generals[lord.deputyGeneral]
      if deputyGeneral then
        for _, s in ipairs(deputyGeneral.skills) do
          if canAttachSkill(lord, s.name) then
            table.insertIfNeed(lord_skills, s.name)
          end
        end
        for _, sname in ipairs(deputyGeneral.other_skills) do
          if canAttachSkill(lord, sname) then
            table.insertIfNeed(lord_skills, sname)
          end
        end
      end
      for _, skill in ipairs(lord_skills) do
        room:doBroadcastNotify("AddSkill", json.encode{
          lord.id,
          skill
        })
      end


      --[[战报显示技能
      local sskills = table.map(Fk.generals[lord_general].skills, function(s) return Fk:translate(s.name).." : "..Fk:translate(":"..s.name) end)
      room:sendLog {
        type = "%from 的主将：<br>%arg技能如下:<br>%arg2",
        from =lord.id,
        arg =lord_general ,
        arg2 =table.concat(sskills, "<br>"),
      }
      if deputy~=nil then
        local ssskills = table.map(Fk.generals[deputy].skills, function(s) return Fk:translate(s.name).." : "..Fk:translate(":"..s.name) end)
        room:sendLog {
          type = "%from 的副将：<br>%arg技能如下:<br>%arg2",
          from =lord.id,
          arg =deputy ,
          arg2 =table.concat(ssskills, "<br>"),
        }

      end

      room:doBroadcastNotify("ShowToast", "<b>" ..Fk:translate("sifuzhongdan_intro"))
      --]]
    end

    local nonlord = room:getOtherPlayers(lord, true)
    local generals = Fk:getGeneralsRandomly(#nonlord * offgennum, nil, lord_generals,
    (function(p) return not Tt.isoff(p) end))
    local prigenerals = Fk:getGeneralsRandomly(#nonlord * prigennum, nil, lord_generals,
    (function(p) return Tt.isoff(p) end))
    if #prigenerals<prigennum then ifpri=false end
    table.shuffle(generals)
    table.shuffle(prigenerals )
    for _, p in ipairs(nonlord) do
      local arg = {}
      for i = 1, offgennum do
        table.insert(arg, table.remove(generals, 1).name)
      end
      if ifpri then
        for i = 1, prigennum do
          table.insert(arg, table.remove(prigenerals, 1).name)
        end
      end
      p.request_data = json.encode{ arg, n }
      p.default_reply = table.random(arg, n)
    end

    room:notifyMoveFocus(nonlord, "AskForGeneral")
    room:doBroadcastRequest("AskForGeneral", nonlord)

    for _, p in ipairs(nonlord) do
      if p.general == "" and p.reply_ready then
        local generals = json.decode(p.client_reply)
        local general = generals[1]
        local deputy = generals[2]
        room:setPlayerGeneral(p, general, true, true)
        room:setDeputyGeneral(p, deputy)
      else
        room:setPlayerGeneral(p, p.default_reply[1], true, true)
        room:setDeputyGeneral(p, p.default_reply[2])
      end
      p.default_reply = ""
    end

    room:askForChooseKingdom(nonlord)
  end

  function vanished_dragon_logic:broadcastGeneral()
    local room = self.room
    local players = room.players
    local lord = room:getTag("ShownLoyalist")

    for _, p in ipairs(players) do
      p:setMark("@seat", 0)
      p:doNotify("SetPlayerMark", json.encode{ p.id, "@seat", 0})
      assert(p.general ~= "")
      local general = Fk.generals[p.general]
      local deputy = Fk.generals[p.deputyGeneral]
      p.maxHp = deputy and math.floor((deputy.maxHp + general.maxHp) / 2)
        or general.maxHp
      p.hp = deputy and math.floor((deputy.hp + general.hp) / 2) or general.hp
      p.shield = math.min(general.shield + (deputy and deputy.shield or 0), 5)
      -- TODO: setup AI here

      if p.id ~= lord then
        room:broadcastProperty(p, "general")
        room:broadcastProperty(p, "kingdom")
        room:broadcastProperty(p, "deputyGeneral")
      elseif #players >=5 then
        p.maxHp = p.maxHp + 1
        p.hp = p.hp + 1
      end
      
      if p.seat>=7 then 
        --p.shield=p.shield+1
        --
        if p.seat>=9 then
          p.shield=p.shield+1
        end
        --]]
      end
      room:broadcastProperty(p, "maxHp")
      room:broadcastProperty(p, "hp")
      room:broadcastProperty(p, "shield")
    end
  end

  function vanished_dragon_logic:attachSkillToPlayers()
    local room = self.room
    local players = room.players
    local lord = room:getTag("ShownLoyalist")
  
    local addRoleModSkills = function(player, skillName)
      local skill = Fk.skills[skillName]
      if skill.lordSkill then
        return
      end
  
      if #skill.attachedKingdom > 0 and not table.contains(skill.attachedKingdom, player.kingdom) then
        return
      end
  
      room:handleAddLoseSkills(player, skillName, nil, false)
    end
    for _, p in ipairs(room.alive_players) do
      local skills = Fk.generals[p.general].skills
      for _, s in ipairs(skills) do
        addRoleModSkills(p, s.name)
      end
      for _, sname in ipairs(Fk.generals[p.general].other_skills) do
        addRoleModSkills(p, sname)
      end
  
      local deputy = Fk.generals[p.deputyGeneral]
      if deputy then
        skills = deputy.skills
        for _, s in ipairs(skills) do
          addRoleModSkills(p, s.name)
        end
        for _, sname in ipairs(deputy.other_skills) do
          addRoleModSkills(p, sname)
        end
      end

      if p.id == lord then
        local skill = (p.maxHp <= 4 and p.gender == General.Male) and "vd_dongcha" or "vd_sheshen"
        room:doBroadcastNotify("ShowToast", Fk:translate("vd_loyalist_skill") .. Fk:translate(skill))
        room:handleAddLoseSkills(p, skill, nil, false)
      end
    end
  end

  return vanished_dragon_logic
end

--明主杀暗忠呢
---@param killer ServerPlayer
local function rewardAndPunish(killer, victim, room)
  if killer.dead then return end
  local shownLoyalist = room:getTag("ShownLoyalist")
  if (victim.id == shownLoyalist and killer.role == "lord") or (victim.role == "loyalist" and killer.id == shownLoyalist) then
    killer:throwAllCards("he")
  elseif victim.role == "rebel" or victim.id == shownLoyalist then
    killer:drawCards(3, "kill")
  end
end

local vanished_dragon_rule = fk.CreateTriggerSkill{
  name = "#vanished_dragon_rule",
  priority = 0.001,
  refresh_events = {fk.GameStart, fk.Deathed,fk.SkillEffect,fk.BeforeCardsMove},
  can_refresh = function(self, event, target, player, data)
    local room = player.room
    if event==fk.BeforeCardsMove then
      if not target==player then return false end
      local room=player.room
      local num=0
      room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function (e)
        for _, move in ipairs(e.data) do
          if move.toArea == Card.PlayerHand and move.to and move.to==player.id then
            for _, info in ipairs(move.moveInfo) do
                num = num + 1
            end
          end
        end
      end, Player.HistoryTurn) 
      return num>=30
    elseif event==fk.SkillEffect then
      return target==player and target and target:hasSkill(data)  and player:usedSkillTimes(data.name, Player.HistoryTurn)>=20
    else
      if event == fk.GameStart then return player.seat == 1 end
      if target ~= player then return false end
      return true
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      room:setTag("SkipNormalDeathProcess", true)
    elseif event==fk.BeforeCardsMove then
      room:doBroadcastNotify("ShowToast", Fk:translate("#drawcards_more"))
      local n=0
      for _, move in ipairs(data) do
        -- p(move)
        --     dbg()
        move.moveInfo={}
      end
      return true
    elseif event==fk.SkillEffect then
      room:setPlayerMark(player, "@@buqun__slience-jbsturn", 1)
    elseif event == fk.Deathed then 
      local damage = data.damage
      if damage and damage.from then
        local killer = damage.from
        rewardAndPunish(killer, player, room)
      end

      local shownLoyalist = room:getTag("ShownLoyalist")
      if player.id == shownLoyalist then
        local lord = room:getLord()
        room:setPlayerProperty(lord, "role_shown", true)
        room:broadcastProperty(lord, "role")
        room:doBroadcastNotify("ShowToast", Fk:translate("vd_lord_exploded") .. Fk:translate(lord.general))
        local skills = Fk.generals[lord.general].skills
        local addLordSkills = function(player, skillName)
          local skill = Fk.skills[skillName]
          if not skill.lordSkill then
            return
          end
          room:handleAddLoseSkills(player, skillName, nil, false)
        end
        for _, s in ipairs(skills) do
          addLordSkills(lord, s.name)
        end
        for _, sname in ipairs(Fk.generals[lord.general].other_skills) do
          addLordSkills(lord, sname)
        end
        local deputy = Fk.generals[lord.deputyGeneral]
        if deputy then
          skills = deputy.skills
          for _, s in ipairs(skills) do
            addLordSkills(lord, s.name)
          end
          for _, sname in ipairs(deputy.other_skills) do
            addLordSkills(lord, sname)
          end
        end
      end
    end
  end,
}

local vanished_dragon = fk.CreateGameMode{
  name = "sfvanished_dragon",
  minPlayer = 6,
  maxPlayer = 10,
  rule = vanished_dragon_rule,
  logic = vanished_dragon_getLogic,
  surrender_func = function(self, playedTime)
    return Fk.game_modes["aaa_role_mode"].surrenderFunc(self, playedTime)
  end,
}




Fk:loadTranslationTable{
  ["sfvanished_dragon"] = "私服忠胆",
  [":sfvanished_dragon"] = desc_vanished_dragon,

  ["sifuzhongdan_intro"]="忠臣已选将，请到信息栏了解详情！",
}

return vanished_dragon
